package com.kurt.service.impl;

import com.kurt.dto.DriverDTO;
import com.kurt.dto.VehicleDTO;
import com.kurt.dto.create.DriverCreateRequest;
import com.kurt.dto.query.DriverQueryRequest;
import com.kurt.dto.update.DriverUpdateRequest;
import com.kurt.entity.SysDriver;
import com.kurt.entity.SysDriverExtension;
import com.kurt.entity.SysVehicle;
import com.kurt.entity.SysVehicleDriver;
import com.kurt.repository.*;
import com.kurt.service.DriverService;
import com.kurt.util.DataPermissionUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 驾驶员服务实现类
 * 实现驾驶员相关的业务逻辑
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DriverServiceImpl extends BaseServiceImpl<SysDriver, Long> implements DriverService {

    private final SysDriverRepository driverRepository;
    private final SysDriverExtensionRepository driverExtensionRepository;
    private final SysOrganizationRepository organizationRepository;
    private final SysVehicleDriverRepository vehicleDriverRepository;
    private final SysVehicleRepository vehicleRepository;
    private final DataPermissionUtil dataPermissionUtil;

    @Override
    protected SysDriverRepository getRepository() {
        return driverRepository;
    }

    @Override
    protected SysDriverRepository getSpecificationExecutor() {
        return driverRepository;
    }

    @Override
    @Transactional
    public DriverDTO createDriver(DriverCreateRequest createRequest) {
        log.info("创建驾驶员: {}", createRequest.getName());

        // 检查身份证号是否已存在
        if (driverRepository.findByIdCard(createRequest.getIdCard()).isPresent()) {
            throw new RuntimeException("身份证号已存在");
        }

        // 检查驾驶证号是否已存在
        if (StringUtils.hasText(createRequest.getDriverLicense()) &&
                driverRepository.findByDriverLicense(createRequest.getDriverLicense()).isPresent()) {
            throw new RuntimeException("驾驶证号已存在");
        }

        // 创建驾驶员实体
        SysDriver driver = new SysDriver();
        BeanUtils.copyProperties(createRequest, driver);
        driver.setCreateTime(LocalDateTime.now());
        driver.setUpdateTime(LocalDateTime.now());

        // 保存驾驶员
        driver = driverRepository.save(driver);

        // 创建驾驶员扩展信息
        if (createRequest.getDriverExtension() != null) {
            SysDriverExtension extension = new SysDriverExtension();
            extension.setId(driver.getId());
            BeanUtils.copyProperties(createRequest.getDriverExtension(), extension);
            extension.setCreateTime(LocalDateTime.now());
            extension.setUpdateTime(LocalDateTime.now());
            driverExtensionRepository.save(extension);
        }

        log.info("驾驶员创建成功: {}", driver.getName());
        return convertToDriverDTO(driver);
    }

    @Override
    @Transactional
    public DriverDTO updateDriver(DriverUpdateRequest updateRequest) {
        log.info("更新驾驶员: {}", updateRequest.getId());

        // 查找驾驶员
        SysDriver driver = getById(updateRequest.getId());

        // 检查身份证号是否已存在（排除自己）
        if (StringUtils.hasText(updateRequest.getIdCard()) &&
                !updateRequest.getIdCard().equals(driver.getIdCard()) &&
                driverRepository.findByIdCard(updateRequest.getIdCard()).isPresent()) {
            throw new RuntimeException("身份证号已存在");
        }

        // 检查驾驶证号是否已存在（排除自己）
        if (StringUtils.hasText(updateRequest.getDriverLicense()) &&
                !updateRequest.getDriverLicense().equals(driver.getDriverLicense()) &&
                driverRepository.findByDriverLicense(updateRequest.getDriverLicense()).isPresent()) {
            throw new RuntimeException("驾驶证号已存在");
        }

        // 更新驾驶员信息
        if (StringUtils.hasText(updateRequest.getName())) {
            driver.setName(updateRequest.getName());
        }
        if (StringUtils.hasText(updateRequest.getIdCard())) {
            driver.setIdCard(updateRequest.getIdCard());
        }
        if (StringUtils.hasText(updateRequest.getPhone())) {
            driver.setPhone(updateRequest.getPhone());
        }
        if (StringUtils.hasText(updateRequest.getDriverLicense())) {
            driver.setDriverLicense(updateRequest.getDriverLicense());
        }
        if (updateRequest.getOrganizationId() != null) {
            driver.setOrganizationId(updateRequest.getOrganizationId());
        }
        if (updateRequest.getStatus() != null) {
            driver.setStatus(updateRequest.getStatus());
        }
        if (StringUtils.hasText(updateRequest.getRemark())) {
            driver.setRemark(updateRequest.getRemark());
        }
        driver.setUpdateTime(LocalDateTime.now());

        // 保存驾驶员
        driver = driverRepository.save(driver);

        // 更新驾驶员扩展信息
        if (updateRequest.getDriverExtension() != null) {
            Optional<SysDriverExtension> extensionOpt = driverExtensionRepository.findById(driver.getId());
            if (extensionOpt.isPresent()) {
                SysDriverExtension extension = extensionOpt.get();
                BeanUtils.copyProperties(updateRequest.getDriverExtension(), extension);
                extension.setUpdateTime(LocalDateTime.now());
                driverExtensionRepository.save(extension);
            } else {
                // 创建新的扩展信息
                SysDriverExtension extension = new SysDriverExtension();
                extension.setId(driver.getId());
                BeanUtils.copyProperties(updateRequest.getDriverExtension(), extension);
                extension.setCreateTime(LocalDateTime.now());
                extension.setUpdateTime(LocalDateTime.now());
                driverExtensionRepository.save(extension);
            }
        }

        log.info("驾驶员更新成功: {}", driver.getName());
        return convertToDriverDTO(driver);
    }

    @Override
    public DriverDTO getDriverById(Long id) {
        SysDriver driver = getById(id);
        return convertToDriverDTO(driver);
    }

    @Override
    public Page<DriverDTO> getDriverPage(DriverQueryRequest queryRequest) {
        // 构建分页参数
        Sort sort = Sort.by(Sort.Direction.fromString(queryRequest.getOrderDirection()), queryRequest.getOrderBy());
        Pageable pageable = PageRequest.of(queryRequest.getPageNum() - 1, queryRequest.getPageSize(), sort);

        // 构建查询条件
        Specification<SysDriver> spec = buildDriverSpecification(queryRequest);

        // 执行分页查询
        Page<SysDriver> driverPage = driverRepository.findAll(spec, pageable);

        // 转换为DTO
        return driverPage.map(this::convertToDriverDTO);
    }

    @Override
    public List<DriverDTO> getDriverList(DriverQueryRequest queryRequest) {
        // 构建查询条件
        Specification<SysDriver> spec = buildDriverSpecification(queryRequest);

        // 执行查询
        List<SysDriver> drivers = driverRepository.findAll(spec);

        // 转换为DTO
        return drivers.stream().map(this::convertToDriverDTO).collect(Collectors.toList());
    }

    @Override
    @Transactional
    public boolean deleteDriver(Long id) {
        log.info("删除驾驶员: {}", id);

        // 删除车辆驾驶员关联
        vehicleDriverRepository.deleteByDriverId(id);

        // 删除驾驶员扩展信息
        driverExtensionRepository.deleteById(id);

        // 删除驾驶员
        driverRepository.deleteById(id);

        log.info("驾驶员删除成功: {}", id);
        return true;
    }

    @Override
    @Transactional
    public boolean deleteDrivers(List<Long> ids) {
        log.info("批量删除驾驶员: {}", ids);

        for (Long id : ids) {
            deleteDriver(id);
        }

        log.info("批量删除驾驶员成功: {}", ids);
        return true;
    }

    @Override
    public List<DriverDTO> getDriversByOrganizationId(Long organizationId) {
        List<SysDriver> drivers = driverRepository.findByOrganizationId(organizationId);
        return drivers.stream().map(this::convertToDriverDTO).collect(Collectors.toList());
    }

    @Override
    public boolean existsByIdCard(String idCard) {
        return driverRepository.findByIdCard(idCard).isPresent();
    }

    @Override
    public boolean existsByIdCardAndIdNot(String idCard, Long excludeId) {
        Optional<SysDriver> driverOpt = driverRepository.findByIdCard(idCard);
        return driverOpt.isPresent() && !driverOpt.get().getId().equals(excludeId);
    }

    @Override
    public boolean existsByDriverLicense(String driverLicense) {
        return driverRepository.findByDriverLicense(driverLicense).isPresent();
    }

    @Override
    public boolean existsByDriverLicenseAndIdNot(String driverLicense, Long excludeId) {
        Optional<SysDriver> driverOpt = driverRepository.findByDriverLicense(driverLicense);
        return driverOpt.isPresent() && !driverOpt.get().getId().equals(excludeId);
    }

    @Override
    @Transactional
    public boolean updateStatus(Long id, Integer status) {
        log.info("更新驾驶员状态: id={}, status={}", id, status);

        SysDriver driver = getById(id);
        driver.setStatus(status);
        driver.setUpdateTime(LocalDateTime.now());
        driverRepository.save(driver);

        log.info("驾驶员状态更新成功: id={}, status={}", id, status);
        return true;
    }

    /**
     * 构建驾驶员查询条件
     *
     * @param queryRequest 查询请求
     * @return 查询条件
     */
    private Specification<SysDriver> buildDriverSpecification(DriverQueryRequest queryRequest) {
        return (root, query, cb) -> {
            List<jakarta.persistence.criteria.Predicate> predicates = new ArrayList<>();

            // 数据权限过滤 - 只查询用户有权限的驾驶员
            Long currentUserId = queryRequest.getLoginUserId();
            if (currentUserId != null) {
                List<Long> authorizedDriverIds = dataPermissionUtil.getAuthorizedResourceIds(currentUserId, "driver");
                predicates.add(root.get("id").in(authorizedDriverIds));
            }

            // 姓名模糊查询
            if (StringUtils.hasText(queryRequest.getName())) {
                predicates.add(cb.like(root.get("name"), "%" + queryRequest.getName() + "%"));
            }

            // 身份证号模糊查询
            if (StringUtils.hasText(queryRequest.getIdCard())) {
                predicates.add(cb.like(root.get("idCard"), "%" + queryRequest.getIdCard() + "%"));
            }

            // 手机号模糊查询
            if (StringUtils.hasText(queryRequest.getPhone())) {
                predicates.add(cb.like(root.get("phone"), "%" + queryRequest.getPhone() + "%"));
            }

            // 驾驶证号模糊查询
            if (StringUtils.hasText(queryRequest.getDriverLicense())) {
                predicates.add(cb.like(root.get("driverLicense"), "%" + queryRequest.getDriverLicense() + "%"));
            }

            // 组织ID查询
            if (queryRequest.getOrganizationId() != null) {
                predicates.add(cb.equal(root.get("organizationId"), queryRequest.getOrganizationId()));
            }

            // 状态查询
            if (queryRequest.getStatus() != null) {
                predicates.add(cb.equal(root.get("status"), queryRequest.getStatus()));
            }

            // 创建时间范围查询
            if (StringUtils.hasText(queryRequest.getCreateTimeStart())) {
                predicates.add(cb.greaterThanOrEqualTo(root.get("createTime"),
                        LocalDateTime.parse(queryRequest.getCreateTimeStart())));
            }
            if (StringUtils.hasText(queryRequest.getCreateTimeEnd())) {
                predicates.add(cb.lessThanOrEqualTo(root.get("createTime"),
                        LocalDateTime.parse(queryRequest.getCreateTimeEnd())));
            }

            return cb.and(predicates.toArray(new jakarta.persistence.criteria.Predicate[0]));
        };
    }

    /**
     * 转换驾驶员实体为DTO
     *
     * @param driver 驾驶员实体
     * @return 驾驶员DTO
     */
    private DriverDTO convertToDriverDTO(SysDriver driver) {
        DriverDTO driverDTO = new DriverDTO();
        BeanUtils.copyProperties(driver, driverDTO);

        // 获取驾驶员扩展信息
        Optional<SysDriverExtension> extensionOpt = driverExtensionRepository.findById(driver.getId());
        if (extensionOpt.isPresent()) {
            DriverDTO.DriverExtensionDTO extensionDTO = new DriverDTO.DriverExtensionDTO();
            BeanUtils.copyProperties(extensionOpt.get(), extensionDTO);
            driverDTO.setDriverExtension(extensionDTO);
        }

        // 获取关联的车辆列表
        List<SysVehicleDriver> vehicleDrivers = vehicleDriverRepository.findByDriverId(driver.getId());
        List<VehicleDTO> vehicles = vehicleDrivers.stream()
                .map(vd -> {
                    Optional<SysVehicle> vehicleOpt = vehicleRepository.findById(vd.getVehicleId());
                    if (vehicleOpt.isPresent()) {
                        VehicleDTO vehicleDTO = new VehicleDTO();
                        BeanUtils.copyProperties(vehicleOpt.get(), vehicleDTO);
                        return vehicleDTO;
                    }
                    return null;
                })
                .filter(vehicle -> vehicle != null)
                .collect(Collectors.toList());
        driverDTO.setVehicles(vehicles);

        return driverDTO;
    }
}
